﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace LiveCodeServer
{
    public class IOHandler
    {
        private const int I_CLIENT_CONNECT_PORT = 8221;

        private Socket socListener;

        private AsyncCallback asynOnClientConnectCallback;

        public Socket Listener
        {
            get
            {
                return this.socListener;
            }
        }
        public AsyncCallback asyncCallback
        {
            set
            {
                this.asynOnClientConnectCallback = value;
            }
        }

        public IOHandler(AsyncCallback clientConnectCallback)
        {
            try
            {
                this.asynOnClientConnectCallback = clientConnectCallback;
                this.StartListening();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public void StartListening()
        {
            try
            {
                //If the socket to listen for incomming connections is null, then create the socket
                if (this.socListener == null)
                {
                    IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, I_CLIENT_CONNECT_PORT);

                    this.socListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                    this.socListener.Bind(ipLocal);
                }
                
                try
                {
                    //Listen for incomming connections
                    this.socListener.Listen(30);
                    //Create the callback for any client connections
                    this.socListener.BeginAccept(new AsyncCallback(this.asynOnClientConnectCallback), null);
                }
                catch (SocketException sExp)
                {
                    //Log and handle error
                    throw sExp;
                }
            }
            catch (Exception e)
            {
                //Log and handle error
                throw e;
            }
        }

        /// <summary>
        /// Closes the default port
        /// </summary>
        public void Disconnect()
        {
            try
            {
                if (this.socListener.Connected)
                {
                    this.socListener.Shutdown(SocketShutdown.Both);
                    this.socListener.Close();
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }
}
